package net.sharpf2.api.types;

import java.awt.Point;
import java.awt.Polygon;
import net.sharpf2.api.Globals;
import net.sharpf2.api.Methods;
import net.sharpf2.api.content.InteractiveContent;
import net.sharpf2.api.interfaces.Menu;
import net.sharpf2.api.interfaces.Minimap;
import net.sharpf2.api.util.Mathematics;
import net.sharpf2.api.world.Space;
import net.sharpf2.sfcore.client.Animable;
import net.sharpf2.sfcore.client.GroundItem;
import net.sharpf2.sfcore.client.Interface;
import net.sharpf2.sfcore.input.Mouse;

/**
 *
 * @author Rick van Biljouw
 * @param <T> Content
 */
public class Content<T> {

    private T content;

    public Content(T content) {
        this.content = content;
    }

    /**
     * Returns actions that can be performed on this type
     * @return actions
     */
    public Actions getActions() {
        return new Actions();
    }

    /**
     * Returns hooks related to this type
     * @return hooks
     */
    public T getContent() {
        return this.content;
    }

    /**
     * Actions to execute.
     */
    public class Actions {

        /**
         * Click content with specific option
         * @param args option
         */
        public void click(String args) {
            if (!Methods.getMyPlayer().getContent().idle()) {
                return;
            }

            if (content instanceof Animable) {
                InteractiveContent c = (InteractiveContent) content;

                Point screen = new Point(-1, -1);
                if (c.getModel() == null || c.getModel().getVerticesX() == null) {
                    screen = Space.get2DCoordinate(c.getLocalX(), c.getLocalY());
                } else {
                    Polygon[] polys = new Model(c.getModel(), new Point(c.getLocalX(), c.getLocalY())).getPolygons();
                    if (polys.length > 0) {
                        Polygon ourPoly = polys[Mathematics.random(0, polys.length - 1)];
                        screen = new Point(ourPoly.xpoints[0], ourPoly.ypoints[0]);
                        int tries = 0;
                        while (!Menu.contains(args) && tries++ < 5 && Mathematics.coordinateOnScreen(screen) && !Thread.currentThread().isInterrupted()) {
                            ourPoly = polys[Mathematics.random(0, polys.length - 1)];
                            screen = new Point(ourPoly.xpoints[0], ourPoly.ypoints[0]);
                            Mouse mouse = Globals.CONTROLLER.getMouse();
                            mouse.move(screen.x, screen.y);
                        }
                    }
                }

                if (Mathematics.coordinateOnScreen(screen)) {
                    Mouse mouse = Globals.CONTROLLER.getMouse();
                    mouse.move(screen.x, screen.y);
                    Menu.getActions().click(args);
                    Methods.sleep(800); //A bit high to be safe
                } else if (c.getWorldPosition().distance(Methods.getMyPlayer().getContent().getWorldPosition()) > 4) {
                    Minimap.clickTile(c.getWorldPosition().x, c.getWorldPosition().y);
                    click(args);
                }
            } else if (content instanceof Interface) {
                Interface i = (Interface) content;
                int centerx = i.getWidth() / 2;
                int centery = i.getHeight() / 2;
                int rx = i.getWidth() > 4 ? Mathematics.random(centerx - 2, centerx + 2) : centerx;
                int ry = i.getHeight() > 4 ? Mathematics.random(centery - 2, centery + 2) : centery;
                Mouse mouse = Globals.CONTROLLER.getMouse();
                mouse.move(i.getAbsoluteX() + rx, i.getAbsoluteY() + ry);
                Menu.getActions().click(args);
            } else if (content instanceof GroundItem) {
                InteractiveContent c = (InteractiveContent) content;
                Point screen = Space.get2DCoordinate(c.getLocalX(), c.getLocalY());
                if (Mathematics.coordinateOnScreen(screen)) {
                    Mouse mouse = Globals.CONTROLLER.getMouse();
                    mouse.move(Space.get2DCoordinate(c.getLocalX(), c.getLocalY()));
                    Menu.getActions().click(args);
                    Methods.sleep(800); //A bit high to be safe
                } else {
                    Minimap.clickTile(c.getWorldPosition().x, c.getWorldPosition().y);
                    click(args);
                }
            }
        }

        /**
         * Left click content
         */
        public void click() {
            if (content instanceof Animable) {
                InteractiveContent c = (InteractiveContent) content;
                Point screen = Space.get2DCoordinate(c.getLocalX(), c.getLocalY());
                if (Mathematics.coordinateOnScreen(screen)) {
                    Mouse mouse = Globals.CONTROLLER.getMouse();
                    mouse.move(Space.get2DCoordinate(c.getLocalX(), c.getLocalY()));
                    mouse.click(true);
                } else {
                    Minimap.clickTile(c.getWorldPosition().x, c.getWorldPosition().y);
                    click();
                }
            } else if (content instanceof Interface) {
                Interface i = (Interface) content;
                int rx = i.getWidth() > 4 ? Mathematics.random(((int) i.getWidth() / 2) - 2, ((int) i.getWidth() / 2) + 2) : ((int) i.getWidth() / 2);
                int ry = i.getHeight() > 4 ? Mathematics.random(((int) i.getHeight() / 2) - 2, ((int) i.getHeight() / 2) + 2) : ((int) i.getHeight() / 2);
                click(i.getAbsoluteX() + rx, i.getAbsoluteY() + ry);
            } else if (content instanceof GroundItem) {
                InteractiveContent c = (InteractiveContent) content;
                Point screen = Space.get2DCoordinate(c.getLocalX(), c.getLocalY());
                if (Mathematics.coordinateOnScreen(screen)) {
                    Mouse mouse = Globals.CONTROLLER.getMouse();
                    mouse.move(Space.get2DCoordinate(c.getLocalX(), c.getLocalY()));
                    mouse.click(true);
                } else {
                    Minimap.clickTile(c.getWorldPosition().x, c.getWorldPosition().y);
                    click();
                }
            }
        }

        /**
         * Click content with specified screen location.
         * @param x X Coordinate.
         * @param y Y Coordinate.
         */
        public void click(int x, int y) {
            if (content instanceof Interface) {
                Mouse mouse = Globals.CONTROLLER.getMouse();
                mouse.move(x, y);
                mouse.click(true);
            }
        }

        /**
         * Hovers mouse over the specified content.
         */
        public void hover() {
            if (content instanceof Animable) {
                InteractiveContent c = (InteractiveContent) content;
                Point screen = Space.get2DCoordinate(c.getLocalX(), c.getLocalY());
                if (Mathematics.coordinateOnScreen(screen)) {
                    Mouse mouse = Globals.CONTROLLER.getMouse();
                    mouse.move(screen.x, screen.y);
                }
            } else if (content instanceof Interface) {
                Interface i = (Interface) content;
                Mouse mouse = Globals.CONTROLLER.getMouse();
                int rx = i.getWidth() > 4 ? Mathematics.random(((int) i.getWidth() / 2) - 2, ((int) i.getWidth() / 2) + 2) : ((int) i.getWidth() / 2);
                int ry = i.getHeight() > 4 ? Mathematics.random(((int) i.getHeight() / 2) - 2, ((int) i.getHeight() / 2) + 2) : ((int) i.getHeight() / 2);
                mouse.move(i.getAbsoluteX() + rx, i.getAbsoluteY() + ry);
            }
        }
    }
}